package com.amz.fc.base;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
import org.springframework.transaction.support.TransactionTemplate;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

@SuppressWarnings("serial")
public abstract class BaseJdbcTemplateCrudAction extends ActionSupport implements ModelDriven<Map<String,String>>, Preparable{
	protected List<Map<String,String>> listModel = new ArrayList<Map<String,String>>();
	protected Map<String,String> editModel = new HashMap<String, String>();
	protected Map<String,String> listFilter = new HashMap<String, String>();
	protected Map<String,String> editFilter = new HashMap<String, String>();
	protected AmzXmlCfgUtil amzCfg = new AmzXmlCfgUtil();
	protected boolean isEditStatus = false;
	
	protected String curMethod = "";
	public static String ADD = "add";
	public static String DEL = "del";
	public static String EDIT = "edit";
	public static String LIST = "list";
	public static String SAVE = "save";
	public static String INSERT = "insert";
	public static String UPDATE = "update";
	
	@Autowired	
	private SimpleJdbcTemplate jdbc;
	
	private TransactionTemplate transactionTemplate;
	
	@Override
	public void prepare() throws Exception {}
	
	@Override
	public String execute() throws Exception {
		list();
		return SUCCESS;
	}
	
	@SuppressWarnings("unchecked")
	public String list(){
		curMethod = LIST;
		String sql = amzCfg.getReadSql(this.getClass(), LIST, listFilter);
		System.out.println(sql.trim());
//		listModel = jdbc.queryForList(sql);
		processListMode();
		return LIST;
	}
	
	public String add(){
		curMethod = ADD;
		processAddMode();
		isEditStatus = false;
		return EDIT;
	}
	
	@SuppressWarnings("unchecked")
	public String edit(){
		curMethod = EDIT;
		String sql = amzCfg.getReadSql(this.getClass(), EDIT, editFilter);
//		editModel = (Map<String,String>)jdbc.queryForMap(sql);
		processEditMode();
		isEditStatus = true;
		return EDIT;
	}
	
	public String save(){
		String ret = null;
		if(isEditStatus) ret = save(UPDATE,editModel);
		if(!isEditStatus)ret = save(INSERT,editModel);
		isEditStatus = true;
		return ret;
	}
	
	public String save(String methodName,Map<String,String> editModel){
		curMethod = methodName;
		SaveSqlInfo saveSqlInfo = amzCfg.getSaveSqlInfo(this.getClass(), methodName, editModel);
		castPrepareArgsClassType(saveSqlInfo);
		try {
			Long pkVal = null;
			if(!isEditStatus){
				pkVal = getInsertPkid();
				saveSqlInfo.setPkVal(pkVal);				
				saveSqlInfo.getPrepareArgsDbval()[0] = pkVal; 
			}			
			int ret = jdbc.update(saveSqlInfo.getPrepareSql(),saveSqlInfo.getPrepareArgsDbval());
			if(ret>0){
				editModel.put(saveSqlInfo.getPkColName(), String.valueOf(pkVal));
				System.out.println("更新成功");
			}
			edit();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("更新失败");
		}
		return EDIT;
	}
	
	public String del(){
		curMethod = DEL;
		return DEL;
	}
	
	public void castPrepareArgsClassType(SaveSqlInfo saveSqlInfo){
//		SqlRowSet metaDataRs = jdbc.queryForRowSet(saveSqlInfo.getMetaDataSql());
		SqlRowSet metaDataRs = null;
		SqlRowSetMetaData metaData = metaDataRs.getMetaData();
		String[] argsStrVals = saveSqlInfo.getPrepareArgsStrVal();
		Object[] argsVals = new Object[argsStrVals.length];
		for (int i = 1; i <=argsStrVals.length; i++) {
			String argsStrVal = argsStrVals[i];
			if(argsStrVal==null) argsVals[i-1] = null;
			metaData.getColumnType(i);
			String className = metaData.getColumnClassName(i);
			Object arg = null;
			if("String".equals(className)){}
			if("java.math.BigDecimal".equals(className)){
				arg = new java.math.BigDecimal(argsStrVal);
			}
			if("Boolean".equals(className)){
				arg = new Boolean(argsStrVal);
			}
			if("Byte".equals(className)){
				
			}
			if("Short".equals(className)){
				arg = new Short(argsStrVal);
			}
			if("Int".equals(className)){
				arg = new Integer(argsStrVal);
			}
			if("Long".equals(className)){
				arg = new Long(argsStrVal);
			}
			if("Float".equals(className)){
				arg = new Float(argsStrVal);
			}
			if("Double".equals(className)){
				arg = new Double(argsStrVal);
			}
			if("byte[]".equals(className)){
				
			}
			if("java.sql.Date".equals(className)){
				arg = java.sql.Date.valueOf(argsStrVal);
			}
			if("java.sql.Time".equals(className)){
				arg = java.sql.Time.valueOf(argsStrVal);
			}
			if("java.sql.Timestamp".equals(className)){
				arg = java.sql.Timestamp.valueOf(argsStrVal);
			}
			
			argsVals[i-1] = arg; 
		}
		
		
		
		
		
		
		
		
		
		
		
	}
	
	public Long getInsertPkid(){
		BigInteger pkVal = (BigInteger)jdbc.queryForObject("SELECT NEXTVAL('syspk')", BigInteger.class);
		return pkVal.longValue();
	}

	
	protected String getListSql(Map<String,String> listFilter){return null;};
	protected String getEditSql(Map<String,String> editFilter){return null;};
	protected String getDelSql(){return null;};
	abstract protected void processListMode();
	abstract protected void processAddMode();
	abstract protected void processEditMode();
	

	@Override
	public Map<String, String> getModel() {
		return editModel;
	}

	
	public SimpleJdbcTemplate getJdbc() {
		return jdbc;
	}

	public void setJdbc(SimpleJdbcTemplate jdbc) {
		this.jdbc = jdbc;
	}

	public List<Map<String, String>> getListModel() {
		return listModel;
	}

	public void setListModel(List<Map<String, String>> listModel) {
		this.listModel = listModel;
	}

	public Map<String, String> getListFilter() {
		return listFilter;
	}

	public void setListFilter(Map<String, String> listFilter) {
		this.listFilter = listFilter;
	}

	public boolean isEditStatus() {
		return isEditStatus;
	}

	public void setEditStatus(boolean isEditStatus) {
		this.isEditStatus = isEditStatus;
	}

	public Map<String, String> getEditModel() {
		return editModel;
	}

	public void setEditModel(Map<String, String> editModel) {
		this.editModel = editModel;
	}

	
}
